package com.yzd.learnjava.concurrency;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.yzd.learnjava.util.Print;

public class NIOInterruption {
	public static void main(String[] args) throws IOException, InterruptedException {
		ExecutorService exec = Executors.newCachedThreadPool();
		ServerSocket server = new ServerSocket(8085);
		InetSocketAddress  address = new InetSocketAddress("localhost", 8085);
		SocketChannel sc = SocketChannel.open(address);
		SocketChannel sc2 = SocketChannel.open(address);
		
		Future<?> f = exec.submit(new NIOBlocked(sc));
		exec.execute(new NIOBlocked(sc2));
		exec.shutdown();
		
		TimeUnit.SECONDS.sleep(1);
		f.cancel(true);
		
		TimeUnit.SECONDS.sleep(1);
		sc2.close();
		
	}
}

class NIOBlocked implements Runnable{
	private final SocketChannel sc ;
	public NIOBlocked(SocketChannel sc) {
		this.sc = sc;
		
	}
	public void run() {
		try {
			Print.print("Waiting for read() in " + this);
			sc.read(ByteBuffer.allocate(1));
		} catch (ClosedByInterruptException e) {
			Print.print("ClosedByInterruptException");
		} catch(AsynchronousCloseException e) {
			Print.print("AsynchronousCloseException");
		} catch(IOException e) {
			Print.print("IOException");
		}
		
		Print.print("exiting NIOBlocked.run() " + this);
	}
}
